import { ButtonHTMLAttributes, ChangeEvent, FC, InputHTMLAttributes, useCallback, useRef, useState } from "react"


// interface IloginParamProps {
//  count: number,
//  width?: number
// //  username: string,
// //  pass: number
// }

// const Child1:FC<IloginParamProps> = (props) => {
//   console.log('props', props)
//    return (<div>
//      用户名：
//      { props.count}
//    </div>)
// }

// const Child1 = (props:IloginParamProps) => {
//     console.log('props', props)
//      return (<div>
//        用户名：
//        { props.count}
//      </div>)
//   }

// const Child1 = ({count}: {count:number}) => {
//     console.log('props', count)
//      return (<div>
//        用户名：
//        { count}
//      </div>)
//   }
interface IloginParamProps {
    count: number,
    width?: number,
    //  username: string,
    //  pass: number
}
// ----推荐下面的写法
// Child2  接口继承
interface Child2Props extends IloginParamProps {
    color: string
}

const Child2: FC<Child2Props> = ({ color, count }) => {
    return (<div>
        child2组件
        <button style={{ color }}>{count}</button>
    </div>);
}

// input 组件 -> placeholder/ value
interface IMyInputProps extends InputHTMLAttributes<HTMLInputElement> {
    color: string,
    borderColor?: string
}
const MyInput: FC<IMyInputProps> = (props) => {
    const style = {
        borderColor: props.borderColor,
        height: '40px',
        lineHeight: '40px',
        color: props.color
    }
    return (<div>
        input: <input {...props} onChange={(e) => {}} style={style} />
    </div>)
}
// button 组件 -> disabled
// <button>发送验证码</button>
//  <button>正在发送..</button>
interface MyButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
    text: string
}
const MyButton: FC<MyButtonProps> = (props) => {
    return (<div>
        <button {...props}>{props.text}</button>
    </div>)
}
// 点击事件
const handlfn1 = (val:string) => {
  console.log('fn1', val)
}
// 获取input的value
const handlefn2 = (e: ChangeEvent<HTMLInputElement>) => {
 // ts校验不通过对时候，能点击快速修复就点
   console.log('e', e.target.value)
} 
// 声明一个对象的类型检查
// 父组件

// 数组
interface IArrValue {
  [index:number]: number
}

// 数组对象

interface IArrObj {
    id: number
  }
// 约束单个对象
interface IUserObj {
  name: string,
  nick: null | string,
  age: number
}
const Child1: FC<IloginParamProps> = ({ count, width = 100 }) => {
    // console.log('props', count)
    // const [num, setcount1] = useState<number>(0) // 基本类型
    // const [arr, setarr] = useState<IArrValue>([12,13]) // arr
    // const [arrObj, setarrObj] = useState<IArrObj[]>([{
    //  id:1
    // }]) 
    // const [obj, setobj] = useState<IUserObj>({
    //   name: '名称',
    //   nick: null,
    //   age: 10
    // })
    // [],[{id:number}], {}
    
    // const hanlefn3 = () => {
    //    setcount1(num + '1')
    // }
    // 项目中使用ts的自动的推导类型
    const [obj, setobj] = useState<IUserObj>({
        name:'zhangsan',
        nick: null,
        age: 18
    })
    const changeNick = (nick:string) => {
       // 1. 先把原来的obj展开放到一个新的对象中，生成一个新的对象
        let nobj = {...obj}
        // 2. 操作新的对象（某个要改的属性）
        nobj.nick = nick
        console.log('obj', nobj)
    
        setobj(() => {
          return {
            ...obj,
            ...nobj
          }
        }) // b1 ={a:1},c1={b:1, a:2} 
        // { ...b1, ...c1} ->  {a:2, b1}
        // Object.assign(b1, c1) -> {a:2, b1}
    }
    // 创建ref对象，获取input内容
    let ref1 = useRef<HTMLInputElement>(null)
    const getRef = () => {
      console.log('ref', ref1.current?.value) // 属性.? -> 可选链
      ref1.current?.focus()
    }
    
    // useCallback -> // useCallback-useMemo->React.memo
    const getById = useCallback((id:number) => {
       console.log('id')
    }, [])
    return (<div>
        <h4>3.1给props默认值</h4>
        count: {count}
        <button style={{ width: width + 'px' }}>读取默认宽度</button>
        {/* 子组件Child2 */}
        <h4>3.2校验props</h4>
        <Child2 color={'red'} count={2} />
        {/* 页面1 */}
        <h4>3.3封装input组件继承元素标签上的属性-extends</h4>
        <MyInput color="green" placeholder='请输入用户信息' />
        {/* 页面2 */}
        <MyInput color="red" placeholder='请输入' value={'345678902345678'} />
        {/* 公用按钮组件 text必填*/}
        <h4>3.4封装button组件继承元素标签上的属性-extends</h4>
        <MyButton text="发送验证码" />
        <MyButton disabled={true} text="正在发送.." />
        <h4>3.5扩展原生标签的属性查找方法：鼠标放到原生标签名上，提示信息中第二行的props后面的两个interface就是</h4>
         <button onClick={()=>handlfn1('11')}>点击函数传参</button>
         {/* onChange */}
         <input onChange={(e) => handlefn2(e) } type="text"  />
         {/* count++ */}
         <h4>3.6 useState</h4>
         <hr/>
         {/* num:{num} */}
         <button onClick={() => changeNick('小花花')}>修改个人信息-昵称</button>
         <pre>
           用户信息：{obj.nick}
         </pre>
         <h3>3.7 useRef</h3>
         <input type="text" ref={ref1} />
         <button onClick={getRef}>getRef</button>
         <button onClick={()=>getById(12) }>getById-useCallback</button>
    </div>)
}


export default Child1